﻿// CheckProjectRunDialog.cpp: 实现文件
//

#include "stdafx.h"
#include "zChecker.h"
#include "CheckProjectRunDialog.h"
#include "afxdialogex.h"

#include "MainFrm.h"


// CCheckProjectRunDialog 对话框
UINT project_run_check_proc(LPVOID pParam)
{
	CCheckProjectRunDialog* pDialog = (CCheckProjectRunDialog*)pParam;
	pDialog->Run();
	return 0;
}

IMPLEMENT_DYNAMIC(CCheckProjectRunDialog, CDialogEx)

CCheckProjectRunDialog::CCheckProjectRunDialog(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_DIALOG_CHECK_PROJECT_RUN, pParent)
{
	m_bAsync = FALSE;
	m_pResultSet = NULL;
}

CCheckProjectRunDialog::~CCheckProjectRunDialog()
{
}

void CCheckProjectRunDialog::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Text(pDX, IDC_EDIT_PROJECT_NAME, m_strProjName);
	DDX_Text(pDX, IDC_EDIT_DATASET_COUNT, m_strDatasetCount);
	DDX_Text(pDX, IDC_EDIT_OUTPUT_PATH, m_strOutputPath);
	DDX_Control(pDX, IDC_PROGRESS1, m_progressBar);
}


BEGIN_MESSAGE_MAP(CCheckProjectRunDialog, CDialogEx)
	ON_WM_CREATE()
	ON_BN_CLICKED(IDOK, &CCheckProjectRunDialog::OnBnClickedOk)
	ON_BN_CLICKED(IDC_BTN_OUTPUT_PATH, &CCheckProjectRunDialog::OnBnClickedBtnOutputPath)
	ON_WM_DESTROY()
	ON_BN_CLICKED(IDCANCEL, &CCheckProjectRunDialog::OnBnClickedCancel)
	ON_MESSAGE(WM_UPDATE_PROJECT_RADIATION_RUN_PROGRESS, &CCheckProjectRunDialog::OnUpdateProgressCtrl)
END_MESSAGE_MAP()


// CCheckProjectRunDialog 消息处理程序


int CCheckProjectRunDialog::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CDialogEx::OnCreate(lpCreateStruct) == -1)
		return -1;

	// TODO:  在此添加您专用的创建代码

	return 0;
}


void CCheckProjectRunDialog::SetProject(ck::CheckProject *pProject)
{
	m_pProject = pProject;
}


BOOL CCheckProjectRunDialog::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// TODO:  在此添加额外的初始化
	if (m_pProject)
	{
		m_strProjName = m_pProject->GetName();
		m_nCount = m_pProject->GetDatasetCount();
		CString str;
		str.Format("%d", m_nCount);
		m_strDatasetCount = str;


		UpdateData(FALSE);

		m_progressBar.SetRange(0, m_nCount);
		//m_progressBar.SetRange(0, 10);
		m_progressBar.SetPos(0);
	}

	return TRUE;  // return TRUE unless you set the focus to a control
				  // 异常: OCX 属性页应返回 FALSE
}


void CCheckProjectRunDialog::OnBnClickedOk()
{
	// TODO: 在此添加控件通知处理程序代码
	UpdateData(TRUE);

	if(m_bAsync)
	{
		CWinThread* pThread = NULL;
		//pThread = AfxBeginThread((AFX_THREADPROC)project_radiation_compute_proc, this, THREAD_PRIORITY_TIME_CRITICAL);
		pThread = AfxBeginThread((AFX_THREADPROC)project_run_check_proc, this);
		DisableControls();

		DWORD dwRet;
		DoEvent();
		do
		{
			dwRet = ::MsgWaitForMultipleObjects(1, &pThread->m_hThread, FALSE, INFINITE, QS_ALLINPUT);
			if (dwRet != WAIT_OBJECT_0)
			{
				DoEvent();
			}
			//else
			//{
			//	AfxMessageBox("here");
			//}
		} while ((dwRet != WAIT_OBJECT_0) && (dwRet != WAIT_FAILED));

		DisableControls();
	}
	else
	{
		Run();
	}


	//

	CLoggerWriter::GetInstance()->Write("计算完成");
	AfxMessageBox("计算完成");

	CDialogEx::OnOK();
}

void CCheckProjectRunDialog::DoEvent()
{
	MSG msg;
	if (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))  //取消息，检索应用程序的消息队列，PM_REMOVE取过之后从消息队列中移除
	{
		//发消息
		::TranslateMessage(&msg);
		::DispatchMessage(&msg);
	}

}


void CCheckProjectRunDialog::OnBnClickedBtnOutputPath()
{
	// TODO: 在此添加控件通知处理程序代码
	char szPath[MAX_PATH]; //存放选择的目录路径 
	CString str;

	ZeroMemory(szPath, sizeof(szPath));
	BROWSEINFO bi;
	bi.hwndOwner = AfxGetMainWnd()->m_hWnd;
	bi.pidlRoot = NULL;
	bi.pszDisplayName = szPath;
	bi.lpszTitle = "请选择GDB目录";
	bi.ulFlags = 0;
	bi.lpfn = NULL;
	bi.lParam = 0;
	bi.iImage = 0;

	LPITEMIDLIST lp = ::SHBrowseForFolder(&bi);
	if (lp && SHGetPathFromIDList(lp, szPath))
	{
		m_strOutputPath = szPath;
		UpdateData(FALSE);
	}

}



void CCheckProjectRunDialog::OnDestroy()
{
	CDialogEx::OnDestroy();

	// TODO: 在此处添加消息处理程序代码
	if (m_pDatasets)
	{
		m_pDatasets->Release();
		m_pDatasets = NULL;
	}
}


void CCheckProjectRunDialog::OnBnClickedCancel()
{
	// TODO: 在此添加控件通知处理程序代码
	//::PostMessage(GetSafeHwnd(), WM_UPDATE_PROJECT_RADIATION_RUN_PROGRESS, (WPARAM)3, 0);

	CDialogEx::OnCancel();
}


void CCheckProjectRunDialog::DisableControls()
{
	GetDlgItem(IDC_EDIT_OUTPUT_PATH)->EnableWindow(FALSE);
	GetDlgItem(IDOK)->EnableWindow(FALSE);
	GetDlgItem(IDCANCEL)->EnableWindow(FALSE);
	GetDlgItem(IDC_BTN_OUTPUT_PATH)->EnableWindow(FALSE);
}

void CCheckProjectRunDialog::EnableControls()
{
	GetDlgItem(IDC_EDIT_OUTPUT_PATH)->EnableWindow(TRUE);
	GetDlgItem(IDOK)->EnableWindow(TRUE);
	GetDlgItem(IDCANCEL)->EnableWindow(TRUE);
	GetDlgItem(IDC_BTN_OUTPUT_PATH)->EnableWindow(TRUE);
}

LRESULT CCheckProjectRunDialog::OnUpdateProgressCtrl(WPARAM wParam, LPARAM lParam)
{
	int pos = (int)wParam;
	m_progressBar.SetPos(pos);
	return 0;
}


void CCheckProjectRunDialog::Run()
{
	ck::DataSource* pDataSource = NULL;
	ck::EnumDataSource* pDataSources = NULL;
	ck::CheckProject* pProject = m_pProject;
	ck::CheckCase* pCase = pProject->GetCheckCase();
	m_pResultSet = new ck::check::CheckResultSet();

	//获取数据产品类型
	ck::ckDataProductType productType = pProject->GetProductType();

	//更新进度条
	//pDialog->m_progressBar.SetPos(1);
	::PostMessage(GetSafeHwnd(), WM_UPDATE_PROJECT_RADIATION_RUN_PROGRESS, (WPARAM)1, 0);

	//遍历工程的DataSource
	int index = 0;
	pDataSources = pProject->GetDataSources();
	pDataSources->Reset();
	while ((pDataSource = pDataSources->Next()))
	{
		//遍历每个DataSource的Dataset
		ck::data::Dataset* pDataset = NULL;
		ck::data::EnumDataset* pDatasets = NULL;
		pDatasets = pDataSource->GetDatasets(productType);
		pDatasets->Reset();
		while ((pDataset = pDatasets->Next()))
		{
			ck::data::Landsat05* pLandsat05 = (ck::data::Landsat05*)pDataset;
			pLandsat05->Open();
			index++;

			TRACE1("%s\n", pLandsat05->GetName());

			//------------------------------------------------------------------------
			//写日志
			//------------------------------------------------------------------------
			char szDataSetPath[_MAX_PATH];
			memset(szDataSetPath, 0, _MAX_PATH);
			strcpy(szDataSetPath, pLandsat05->GetPath());
			CLoggerWriter::GetInstance()->Write(szDataSetPath);

			Check(pDataset, pCase);

			::PostMessage(GetSafeHwnd(), WM_UPDATE_PROJECT_RADIATION_RUN_PROGRESS, (WPARAM)index, 0);
		}

		pDatasets->Release();
	}
	pDataSources->Release();

	m_pProject->SetCheckResultSet(m_pResultSet);
	if (m_pResultSet)
	{
		m_pResultSet->AddRef();
	}

	CMainFrame* pFrmMain = (CMainFrame*)AfxGetMainWnd();
	pFrmMain->m_wndOutput.PopulateCheckResult(m_pResultSet);
	m_pResultSet->Release();

}


void CCheckProjectRunDialog::Check(ck::data::Dataset* pDataset, ck::CheckCase* pCase)
{
	const char* szOperName = NULL;
	ck::Operator* pOperator = NULL;
	ck::EnumOperator* pOperators = pCase->GetOperators();
	pOperators->Reset();
	while ((pOperator = pOperators->Next()))
	{
		szOperName = pOperator->GetName();

		pOperator->SetParameter(0, pDataset);
		pOperator->Run();

		ck::check::CheckResult* pResult = NULL;
		pResult = pOperator->GetResult();
		if (pResult)
		{
			m_pResultSet->Add(pResult);
		}
	}
}